home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / stterm / term.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  266 lines

  1. /* minix doesn't suport open(path, oflag, mode) so no NODELAY        */
  2.  
  3. /* my work around is to run term as 2 procs one that reads /dev/tty1    */
  4. /* and one that writes to it.  Now if we block for reading it doesn't    */
  5. /* matter.                                */
  6.  
  7. /*
  8.  * enhancements:
  9.  * usage: term [-s speed] [-l line] [-e escape-char]
  10.  *    defaults:
  11.  *        speed:  9600      -- see const.h
  12.  *        line :  /dev/tty1 -- see const.h
  13.  *        escape: ~      -- see const.h
  14.  *                escape char may be specified as three octal digits
  15.  *
  16.  *    term escapes: (see man tip) -- more to come
  17.  *        escape-. or escape-CTRLD    terminate
  18.  *        escape-!            escape to shell
  19.  *        escape-#            send break
  20.  *        escape-escape            send escape char
  21.  *
  22.  *    ++jrb    bammi@dsrgsun.ces.cwru.edu
  23.  */
  24.  
  25. #include <sys/types.h>
  26. #include <signal.h>
  27. #include <sgtty.h>
  28. #include <fcntl.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include "const.h"
  32.  
  33. #ifndef R_OK        /* access() modes */
  34. #define R_OK 4
  35. #define W_OK 2
  36. #endif
  37.  
  38. char *i_am = "term";        /* name used in err() */
  39. extern void err();          /* error printing routine */
  40. extern void s_line();       /* set & save line characteristics   */
  41. extern void r_line();       /* reset saved  line characteristics */
  42.  
  43. static int rd_pid, wr_pid;       /* reader/writer process id's */
  44. static int line_fd;           /* comm line file desc        */
  45. static int con_fd;           /* console   file desc        */
  46.  
  47. static struct sgttyb con, con_save, /* console line characteristics */
  48.                    line, line_save; /* comm    line characteristics */
  49.  
  50. #ifdef __STDC__
  51. void cleanup(int foo)
  52. #else
  53. int cleanup()
  54. #endif
  55. {
  56.   r_line();
  57.   kill(rd_pid, SIGTERM);
  58.   kill(wr_pid, SIGTERM);
  59.  
  60.   exit(0);
  61. }
  62.  
  63. void main(argc, argv)
  64. int argc;
  65. char **argv;
  66. {
  67.   int done, status;
  68.   int speed = SPEED;
  69.   char device[32];
  70.   char esc[2];
  71.   extern char *optarg;
  72.   extern int getopt(), conv_speed(), conv_esc(), access();
  73.   extern char *itoa();
  74.   
  75.   esc[0] = ESC;
  76.   esc[1] = '\0';  
  77.   strcpy(device, LINE);
  78.   while((status = getopt(argc, argv,"s:l:e:")) != EOF)
  79.   {
  80.       switch(status)
  81.       {
  82.     case 's':
  83.       if((speed = conv_speed(optarg)) == EOF)
  84.       {
  85.           fprintf(stderr,"%s: invalid speed\n", optarg);
  86.           exit(1);
  87.       }
  88.       break;
  89.     case 'l':
  90.       strncpy(device, optarg, (int)sizeof device); /* avoid screwage */
  91.       if(access(device, R_OK|W_OK) == EOF)
  92.       {
  93.           perror(optarg);
  94.           exit(2);
  95.       }
  96.       break;
  97.     case 'e':
  98.       esc[0] = conv_esc(optarg);
  99.       break;
  100.     default:
  101.       fprintf(stderr,
  102.           "usage: %s [-s speed] [-l line] [-e escape-char]\n", *argv);
  103.       exit(3);
  104.       }
  105.   }
  106.  
  107.   if((line_fd = open(device, O_RDWR)) < 0)
  108.   {
  109.       perror(device);
  110.       exit(4);
  111.   }
  112.   con_fd = fileno(stdin);
  113.  
  114.   /* set line chars. semi-atomically */
  115.   signal(SIGINT, SIG_IGN);
  116.   signal(SIGQUIT, SIG_IGN);
  117.  
  118.   s_line(speed);
  119.   
  120.   signal(SIGINT, cleanup);
  121.   signal(SIGQUIT, cleanup);
  122.  
  123. /* launch reader process */
  124.   if (rd_pid = fork()) {
  125.     if (rd_pid == -1)
  126.         err("fork tty reader");
  127.   } else {
  128.         /* re-dir stdin */
  129.       close(fileno(stdin));
  130.       dup(line_fd);
  131. #if 0
  132. #ifdef TIOCSTART
  133.       if (ioctl(0, TIOCSTART, 0) == ERR)
  134.         err("reset comm line");
  135. #endif
  136. #endif
  137.     
  138.     execlp("read_tty", "read_tty", (char *)0);
  139.   }
  140.  
  141. /* launch writer process */
  142.   if (wr_pid = fork()) {
  143.     if (wr_pid == -1)
  144.         err("fork tty writer");
  145.   } else {
  146.         /* re-dir stdout */
  147.       close(fileno(stdout));
  148.       dup(line_fd);
  149.       execlp("write_tty", "write_tty", esc, itoa(rd_pid), (char *)0);
  150.   }
  151.  
  152.  
  153.   done = wait(&status);
  154.   cleanup(1);
  155. }
  156.  
  157. typedef struct
  158. {
  159.     char *str;
  160.     int  spd;
  161. } vspeeds;
  162.  
  163. static vspeeds valid_speeds[] = 
  164. {
  165.    { "110",  B110  },
  166.    { "300",  B300  },
  167.    { "1200", B1200 },
  168.    { "2400", B2400 },
  169.    { "4800", B4800 },
  170.    { "9600", B9600 },
  171.    { (char *)NULL, 0 }
  172. };
  173.  
  174. /*
  175.  * given a desired speed string, if valid return its Bspeed value
  176.  * else EOF
  177.  */
  178. int conv_speed(s)
  179. register char *s;
  180. {
  181.     register vspeeds *p = &valid_speeds[0];
  182.     
  183.     for(; p->str != (char *)NULL; p++)
  184.     if(strcmp(s, p->str) == 0)
  185.         return p->spd;
  186.     return EOF;
  187. }
  188.  
  189. #include <ctype.h>
  190. #define ISOCTAL(x)    (('0' <= (x)) && ((x) <= '7'))
  191. /*
  192.  * convert given string to char
  193.  *    string maybe a char, or octal digits
  194.  */
  195. int conv_esc(s)
  196. register char *s;
  197. {
  198.     register int val = 0;
  199.     
  200.     if(!isdigit(*s))
  201.     return *s; /* ! octal */
  202.     
  203.     /* convert octal digs */
  204.     do
  205.     {
  206.     if(!ISOCTAL(*s))
  207.     {
  208.         fprintf(stderr,"escape char must be character/octal digits\n");
  209.         exit(4);
  210.     }
  211.     val = (val << 3) + (*s++ - '0');
  212.     } while(isdigit(*s));
  213.  
  214.     return val;
  215. }
  216.  
  217. /*
  218.  * condition lines
  219.  */
  220. void s_line(speed)
  221. int speed;
  222. {
  223.     if(ioctl(con_fd, TIOCGETP, &con) == EOF)
  224.     {
  225.     perror("console");
  226.     exit(5);
  227.     }
  228.     if(ioctl(line_fd, TIOCGETP, &line) == EOF)
  229.     {
  230.     perror("comm line");
  231.     exit(6);
  232.     }
  233.     con_save = con;
  234.     line_save = line;
  235.  
  236.     con.sg_flags &= ~ECHO;
  237.     con.sg_flags |= RAW;
  238.     
  239.     line.sg_flags &= ~ECHO;
  240.     line.sg_flags |= RAW;
  241.     line.sg_ispeed = line.sg_ospeed = speed;
  242.     
  243.     if(ioctl(con_fd, TIOCSETP, &con) == EOF)
  244.     {
  245.     perror("console");
  246.     exit(7);
  247.     }
  248.     if(ioctl(line_fd, TIOCSETP, &line) == EOF)
  249.     {
  250.     perror("comm line");
  251.     exit(8);
  252.     }
  253. }
  254.  
  255. /*
  256.  * reset lines
  257.  */
  258. void r_line()
  259. {
  260.     if( (ioctl(con_fd, TIOCSETP, &con_save)   == EOF) ||
  261.         (ioctl(line_fd, TIOCSETP, &line_save) == EOF))
  262.     {
  263.     fprintf(stderr,"warning: could not reset a line\n");
  264.     }
  265. }    
  266.